package com.zhiche.lisa.bms.service.driver.impl;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.google.common.collect.Lists;
import com.zhiche.lisa.bms.dao.mapper.driver.FuelPriceEffectiveMapper;
import com.zhiche.lisa.bms.dao.model.driver.FuelPriceEffective;
import com.zhiche.lisa.bms.pojo.vo.driver.FuelPriceEffectiveQueryConditionsVO;
import com.zhiche.lisa.bms.pojo.vo.driver.FuelPriceEffectiveVO;
import com.zhiche.lisa.bms.service.driver.IFuelPriceEffectiveService;
import com.zhiche.lisa.bms.utils.ToolCommonUtils;
import com.zhiche.lisa.core.supports.BaseException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.joda.time.DateTime;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.validation.BindingResult;
import org.springframework.validation.ObjectError;

import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * <p>
 * 燃油价格生效表 服务实现类
 * </p>
 *
 * @author zhaoguixin
 * @since 2018-08-30
 */
@Service
@Slf4j
public class FuelPriceEffectiveServiceImpl extends ServiceImpl<FuelPriceEffectiveMapper, FuelPriceEffective> implements IFuelPriceEffectiveService {

    /**
     * 分页查询
     *
     * @param pageVO
     * @return
     */
    @Override
    public Page<FuelPriceEffectiveVO> listByPage(Page<FuelPriceEffectiveVO> pageVO) {
        if (Objects.isNull(pageVO)) {
            return null;
        }
        pageVO.setOrderByField("create_time");
        pageVO.setAsc(false);
        EntityWrapper<FuelPriceEffectiveVO> ew = whereCondition(pageVO);
        List<FuelPriceEffectiveVO> list = baseMapper.selectByConditions(pageVO, ew);
        pageVO.setRecords(list);
        return pageVO;
    }

    /**
     * 添加
     *
     * @param fuelPriceEffectiveVO
     * @param br
     * @return
     */
    @Override
    public Integer add(FuelPriceEffectiveVO fuelPriceEffectiveVO, BindingResult br) {
        log.info("FuelPriceEffectiveServiceImpl.add params : {}", fuelPriceEffectiveVO);

        if (Objects.isNull(fuelPriceEffectiveVO)) {
            log.error("FuelPriceEffectiveServiceImpl.add param form must not be null");
            throw new BaseException("燃油价格变动表单不能为空");
        }

        // 时间格式化
        updateEffectiveAndInvateDate(fuelPriceEffectiveVO);

        //验证表单
        verificationForm(br);

        //验证业务
        verificationBusiness(fuelPriceEffectiveVO);

        /**
         * 查询当前生效的记录，更新失效时间未添加记录的生效时间
         */
        FuelPriceEffective currentPrice = this.selectByEffectiveDateAndFuelTypeId(fuelPriceEffectiveVO.getFuelTypeId(), fuelPriceEffectiveVO.getEffectiveDate());
        if (Objects.nonNull(currentPrice)) {
            currentPrice.setInvalidDate(fuelPriceEffectiveVO.getEffectiveDate());
            this.updateById(currentPrice);
        }

        /**
         * 生成车型每公里油费变动
         */
//        dVehiclePreKilometerFeeEffectiveService.automaticGeneration(effective.getFuelTypeId(), effective.getId(), effective.getMarketPrice(), effective.getEffectiveDate());

        FuelPriceEffective effective = new FuelPriceEffective();
        BeanUtils.copyProperties(fuelPriceEffectiveVO, effective);
        this.insert(effective);
        return effective.getId();
    }

    /**
     * 更新
     *
     * @param fuelPriceEffectiveVO
     * @param br
     * @return
     */
    @Override
    public Boolean update(FuelPriceEffectiveVO fuelPriceEffectiveVO, BindingResult br) {
        log.info("FuelPriceEffectiveServiceImpl.update param : {}", fuelPriceEffectiveVO);

        if (Objects.isNull(fuelPriceEffectiveVO)) {
            log.error("FuelPriceEffectiveServiceImpl.update param form must not be null");
            throw new IllegalArgumentException("燃油价格变动表单不能为空");
        }

        // 时间格式化
        updateEffectiveAndInvateDate(fuelPriceEffectiveVO);

        //验证表单
        verificationForm(br);

        //验证业务
        verificationBusiness(fuelPriceEffectiveVO);

        /**
         * 新增燃油价格变动信息时更新上一条的失效时间为新增记录的生效时间
         */
        FuelPriceEffective currentPrice = selectByEffectiveDateAndFuelTypeId(fuelPriceEffectiveVO.getFuelTypeId(), fuelPriceEffectiveVO.getEffectiveDate());
        if (Objects.nonNull(currentPrice)) {
            currentPrice.setInvalidDate(fuelPriceEffectiveVO.getEffectiveDate());
            this.updateById(currentPrice);
        }

        /**
         * 更新车型每公里油费变动
         */
//        dVehiclePreKilometerFeeEffectiveService.updateByDFuelPriceEffective(effective.getId(), effective.getMarketPrice(), effective.getEffectiveDate());

        FuelPriceEffective effective = new FuelPriceEffective();
        BeanUtils.copyProperties(fuelPriceEffectiveVO, effective);
        return this.updateById(effective);
    }

    /**
     * 时间格式化
     *
     * @param fuelPriceEffectiveVO
     */
    private void updateEffectiveAndInvateDate(FuelPriceEffectiveVO fuelPriceEffectiveVO) {
        // 时间格式化
        if (Objects.nonNull(fuelPriceEffectiveVO.getEffectiveDate())) {
            fuelPriceEffectiveVO.setEffectiveDate(ToolCommonUtils.getStartOfDate(fuelPriceEffectiveVO.getEffectiveDate()));
        }
        if (Objects.nonNull(fuelPriceEffectiveVO.getInvalidDate())) {
            fuelPriceEffectiveVO.setInvalidDate(ToolCommonUtils.getStartOfDate(fuelPriceEffectiveVO.getInvalidDate()));
        }
    }

    /**
     * 删除
     *
     * @param id
     * @return
     * @throws BaseException
     */
    @Override
    public Boolean del(Integer id) throws BaseException {
        log.info("FuelPriceEffectiveServiceImpl.delete param : {}", id);

        if (Objects.isNull(id) || id.equals(0)) {
            log.error("FuelPriceEffectiveServiceImpl.del param id must not be null");
            throw new BaseException("主键不能为空");
        }

        FuelPriceEffective effective = selectById(id);
        if (Objects.isNull(effective)) {
            log.error("FuelPriceEffectiveServiceImpl.del mile is null");
            throw new BaseException("记录不存在");
        }

        Date today = new DateTime().withMillisOfDay(0).toDate();
        if (1 > effective.getEffectiveDate().compareTo(today)) {
            log.error("FuelPriceEffectiveServiceImpl.del mile can not delete");
            throw new BaseException("只能删除未生效的记录");
        }

        this.deleteById(id);

        //更新当前记录失效时间为空
        FuelPriceEffective currentEffective = this.selectByEffectiveDateAndFuelTypeId(effective.getFuelTypeId(), new Date());
        if (Objects.nonNull(currentEffective)) {
            currentEffective.setInvalidDate(null);
            this.updateById(currentEffective);
        }
        return true;
    }


    /**
     * 根据条件查询
     *
     * @param fuelPriceEffectiveQueryConditionsVO@return
     */
    @Override
    public List<FuelPriceEffectiveVO> selectListByConditions(FuelPriceEffectiveQueryConditionsVO fuelPriceEffectiveQueryConditionsVO) {
        log.info("FuelPriceEffectiveServiceImpl.selectListByConditions params : {}", fuelPriceEffectiveQueryConditionsVO);

        EntityWrapper<FuelPriceEffective> ew = new EntityWrapper<>();

        if (StringUtils.isNotBlank(fuelPriceEffectiveQueryConditionsVO.getName())) {
            ew.like("name", fuelPriceEffectiveQueryConditionsVO.getName());
        }

        if (Objects.nonNull(fuelPriceEffectiveQueryConditionsVO.getFuelTypeId())) {
            ew.eq("fuel_type_id", fuelPriceEffectiveQueryConditionsVO.getFuelTypeId());
        }

        if (Objects.nonNull(fuelPriceEffectiveQueryConditionsVO.getEffectiveDate())) {
            ew.ge("effective_date", fuelPriceEffectiveQueryConditionsVO.getEffectiveDate());
        }

        if (Objects.nonNull(fuelPriceEffectiveQueryConditionsVO.getInvalidDate())) {
            ew.lt("invalid_date", fuelPriceEffectiveQueryConditionsVO.getInvalidDate());
        }
        List<FuelPriceEffective> list = this.selectList(ew);
        List<FuelPriceEffectiveVO> listVO = Lists.newArrayList();
        list.forEach(fuelPriceEffective -> {
            FuelPriceEffectiveVO vo = new FuelPriceEffectiveVO();
            BeanUtils.copyProperties(fuelPriceEffective, vo);
            listVO.add(vo);
        });

        return listVO;
    }

    /**
     * 根据ID查询
     *
     * @param id
     * @return
     */
    @Override
    public FuelPriceEffectiveVO getById(Integer id) {
        EntityWrapper<FuelPriceEffectiveVO> ew = new EntityWrapper<>();
        ew.eq("id", id);
        return baseMapper.getOneByEW(ew);
    }

    private EntityWrapper<FuelPriceEffectiveVO> whereCondition(Page<FuelPriceEffectiveVO> page) {
        EntityWrapper<FuelPriceEffectiveVO> ew = new EntityWrapper<>();
        //条件
        if (Objects.nonNull(page.getCondition())) {
            //名称
            if (Objects.nonNull(page.getCondition().get("name")) && StringUtils.isNotEmpty(page.getCondition().get("name").toString())) {
                ew.like("name", page.getCondition().get("name").toString().trim());
            }
            if (Objects.nonNull(page.getCondition().get("fuelTypeId")) && StringUtils.isNotEmpty(page.getCondition().get("fuelTypeId").toString())) {
                ew.eq("fuel_type_id", page.getCondition().get("fuelTypeId").toString().trim());
            }
            if (Objects.nonNull(page.getCondition().get("effectiveDate")) && StringUtils.isNotEmpty(page.getCondition().get("effectiveDate").toString())) {
                ew.ge("effective_date", page.getCondition().get("effectiveDate").toString().trim());
            }
            if (Objects.nonNull(page.getCondition().get("invalidDate")) && StringUtils.isNotEmpty(page.getCondition().get("effectiveDate").toString())) {
                ew.lt("invalid_date", page.getCondition().get("invalidDate").toString().trim());
            }

        }
        return ew;
    }

    private void verificationForm(BindingResult br) {

        if (null == br) {
            log.error("FuelPriceEffectiveServiceImpl.verificationForm error br is null");
            throw new IllegalArgumentException("BindingResult is null");
        }

        if (br.hasErrors()) {
            List<ObjectError> list = br.getAllErrors();
            log.error("FuelPriceEffectiveServiceImpl.verificationForm error : {}", list.get(0).getDefaultMessage());
            throw new BaseException(list.get(0).getDefaultMessage());
        }
    }

    private void verificationBusiness(FuelPriceEffectiveVO form) {
        log.info("FuelPriceEffectiveServiceImpl.verificationBusiness param : {}", form);

        EntityWrapper<FuelPriceEffective> ew = new EntityWrapper<>();
        ew.eq("fuel_type_id", form.getFuelTypeId());
        ew.ge("effective_date", form.getEffectiveDate());
        ew.andNew().le("invalid_date", form.getEffectiveDate()).or().isNull("invalid_date");
        List<FuelPriceEffective> list = this.selectList(ew);


        if (CollectionUtils.isEmpty(list)) {
            return;
        }

        // /**
        //  * 是否已经存在未激活的里程变动
        //  * 激活时间大于
        //  */
        // List<FuelPriceEffective> collect = list.stream().filter(
        //         o -> -1 != o.getEffectiveDate().compareTo(new DateTime().withMillisOfDay(0).toDate() )
        // ).collect(Collectors.toList());

        if (CollectionUtils.isNotEmpty(list)) {

            if (Objects.nonNull(form.getId())) {
                if (CollectionUtils.isNotEmpty(list.stream().filter(o -> o.getId().equals(form.getId())).collect(Collectors.toList()))) {
                    return;
                }
            }

            if (list.size() >= 1) {
                log.error("FuelPriceEffectiveServiceImpl.verificationBusiness already exist not active record");
                throw new BaseException("油价变动已经存在未生效的记录");
            }

            FuelPriceEffective effective = list.get(0);
            if (Objects.nonNull(form.getId()) && form.getId().equals(effective.getId())) {
                return;
            }
            if (form.getEffectiveDate().compareTo(effective.getEffectiveDate()) == 1) {
                return;
            }

            log.error("FuelPriceEffectiveServiceImpl.verificationBusiness already exist not active record");
            throw new BaseException("油价变动已经存在未生效的记录");
        }
    }

    @Override
    public FuelPriceEffective selectByEffectiveDateAndFuelTypeId(Integer fuelTypeId, Date effectiveDate) {
        log.info("FuelPriceEffectiveServiceImpl.selectByEffectiveDateAndFuelTypeId params : {}, {}", fuelTypeId, effectiveDate);

        if (Objects.isNull(fuelTypeId)) {
            log.error("FuelPriceEffectiveServiceImpl.selectByEffectiveDateAndFuelTypeId param fuelTypeId must not be null");
            throw new BaseException("燃油类型主键不能为空");
        }

        if (Objects.isNull(effectiveDate)) {
            log.error("FuelPriceEffectiveServiceImpl.selectByEffectiveDateAndFuelTypeId param effectiveDate must not be null");
            throw new IllegalArgumentException("生效时间不能为空");
        }

        EntityWrapper<FuelPriceEffective> ew = new EntityWrapper<>();
        ew.eq("fuel_type_id", fuelTypeId)
                .le("effective_date", effectiveDate)
                .and("invalid_date is null");

        List<FuelPriceEffective> list = this.selectList(ew);

        if (CollectionUtils.isEmpty(list)) {
            EntityWrapper<FuelPriceEffective> ew2 = new EntityWrapper<>();
            ew2.eq("fuel_type_id", fuelTypeId)
                    .le("effective_date", effectiveDate)
                    .gt("invalid_date", effectiveDate);
            list = this.selectList(ew2);
        }

        if (CollectionUtils.isNotEmpty(list)) {
            return list.get(0);
        }

        return null;
    }
}
